#include "lcd_init.h"
#include "lcd.h"

#include "bd_gps.h"
#include "stdio.h"
#include "ble.h"

#include "FreeRTOS.h"
#include "task.h"
#include "cmsis_os.h"

extern struct BD_GPS_STRUCT bd_gps_s;
extern struct BD_GPS_STRUCT bd_gps_car_s;
extern struct CAR_VALUE_STRUCT car_value_s;

extern enum BLE_STATUS_ENUM ble_status;

extern char key_code;

#define LCD_DC_Set() HAL_GPIO_WritePin(LCD_DC_GPIO_Port, LCD_DC_Pin, GPIO_PIN_SET);
#define LCD_DC_Clr() HAL_GPIO_WritePin(LCD_DC_GPIO_Port, LCD_DC_Pin, GPIO_PIN_RESET);

#define LCD_RES_Set() HAL_GPIO_WritePin(LCD_RES_GPIO_Port, LCD_RES_Pin, GPIO_PIN_SET);
#define LCD_RES_Clr() HAL_GPIO_WritePin(LCD_RES_GPIO_Port, LCD_RES_Pin, GPIO_PIN_RESET);

#define LCD_BLK_Set() HAL_GPIO_WritePin(LCD_BLK_GPIO_Port, LCD_BLK_Pin, GPIO_PIN_SET);
#define LCD_BLK_Clr() HAL_GPIO_WritePin(LCD_BLK_GPIO_Port, LCD_BLK_Pin, GPIO_PIN_RESET);

extern SPI_HandleTypeDef hspi1;

void StartLCDTask(void const *argument)
{
    char str[128];
    lcd_init();
    
    LCD_ShowString(0,0,"RC BD STATUS:",RED,BLACK,16,0);
    LCD_ShowString(0,16,"RC BD :",RED,BLACK,16,0);

    LCD_ShowString(0,16*3,"CARBD STATUS:",RED,BLACK,16,0);
    LCD_ShowString(0,16*4,"CARBD :",RED,BLACK,16,0);
    
    LCD_ShowString(0,16*12,"ANGLE:",RED,BLACK,16,0);
    LCD_ShowString(0,16*13,"KEY CODE:",RED,BLACK,16,0);
    LCD_ShowString(0,16*14,"BLE STATUS:",RED,BLACK,16,0);
    
    while(1)
    {
        sprintf(str,"%.2f",car_value_s.MagAngle);
        LCD_ShowString(8*16,16*12,str,GREEN,BLACK,16,0);
        
        sprintf(str,"%.2f",car_value_s.angle);
        LCD_ShowString(8*7,16*12,str,GREEN,BLACK,16,0);
        
        sprintf(str,"%02X",key_code);
        LCD_ShowString(8*10,16*13,str,GREEN,BLACK,16,0);
    
        if(ble_status == BLE_CONNECTING)
        {
            LCD_ShowString(8*12,16*14,"CONNECTING",YELLOW,BLACK,16,0);
        }else{
            LCD_ShowString(8*12,16*14,"CONNECTED ",GREEN,BLACK,16,0);
        }
        
        if(bd_gps_s.status == BD_GPS_STATUS_VAILD)
        {
            LCD_ShowString(8*14,0,"A",GREEN,BLACK,16,0);
            
            sprintf(str,"%f%c  %f%c",bd_gps_s.lat,bd_gps_s.lat_char,bd_gps_s.lng,bd_gps_s.lng_char);
            LCD_ShowString(8*2,16*2,(const uint8_t*)str,BLUE,BLACK,16,0);  
            
        }else if(bd_gps_s.status == BD_GPS_STATUS_INVAILD){
            
            LCD_ShowString(8*14,0,"V",YELLOW,BLACK,16,0);
            sprintf(str,"                              ");
            LCD_ShowString(8*2,16*2,(const uint8_t*)str,RED,BLACK,16,0);  
        }else{
            LCD_ShowString(8*14,0,"N",YELLOW,BLACK,16,0);
            sprintf(str,"                              ");
            LCD_ShowString(8*2,16*2,(const uint8_t*)str,RED,BLACK,16,0);  
        }

        if(bd_gps_car_s.status == BD_GPS_STATUS_VAILD)
        {
            LCD_ShowString(8*14,16*3,"A",GREEN,BLACK,16,0);
            
            sprintf(str,"%f%c  %f%c",bd_gps_car_s.lat,bd_gps_car_s.lat_char,bd_gps_car_s.lng,bd_gps_car_s.lng_char);
            LCD_ShowString(8*2,16*5,(const uint8_t*)str,BLUE,BLACK,16,0);  
            
        }else if(bd_gps_car_s.status == BD_GPS_STATUS_INVAILD){
            
            LCD_ShowString(8*14,16*3,"V",YELLOW,BLACK,16,0);
            sprintf(str,"                              ");
            LCD_ShowString(8*2,16*5,(const uint8_t*)str,RED,BLACK,16,0);  
        }else{
            LCD_ShowString(8*14,16*3,"N",YELLOW,BLACK,16,0);
            sprintf(str,"                              ");
            LCD_ShowString(8*2,16*5,(const uint8_t*)str,RED,BLACK,16,0);  
        }
        
        
        osDelay(1000);
        HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    }
}

void lcd_init(void)
{
	LCD_RES_Clr();
    osDelay(120);
    LCD_RES_Set();
    
    LCD_BLK_Set();
    osDelay(120);
    
	LCD_WR_REG(0x11);           //Sleep out 
	osDelay(120);               //Delay 120ms 
	LCD_WR_REG(0x36);
    
	if(USE_HORIZONTAL==0)LCD_WR_DATA8(0x00);
	else if(USE_HORIZONTAL==1)LCD_WR_DATA8(0xC0);
	else if(USE_HORIZONTAL==2)LCD_WR_DATA8(0x70);
	else LCD_WR_DATA8(0xA0);

	LCD_WR_REG(0x3A); 
	LCD_WR_DATA8(0x05);

	LCD_WR_REG(0xB2);
	LCD_WR_DATA8(0x0C);
	LCD_WR_DATA8(0x0C);
	LCD_WR_DATA8(0x00);
	LCD_WR_DATA8(0x33);
	LCD_WR_DATA8(0x33); 

	LCD_WR_REG(0xB7); 
	LCD_WR_DATA8(0x35);  

	LCD_WR_REG(0xBB);
	LCD_WR_DATA8(0x19);

	LCD_WR_REG(0xC0);
	LCD_WR_DATA8(0x2C);

	LCD_WR_REG(0xC2);
	LCD_WR_DATA8(0x01);

	LCD_WR_REG(0xC3);
	LCD_WR_DATA8(0x12);   

	LCD_WR_REG(0xC4);
	LCD_WR_DATA8(0x20);  

	LCD_WR_REG(0xC6); 
	LCD_WR_DATA8(0x0F);    

	LCD_WR_REG(0xD0); 
	LCD_WR_DATA8(0xA4);
	LCD_WR_DATA8(0xA1);

	LCD_WR_REG(0xE0);
	LCD_WR_DATA8(0xD0);
	LCD_WR_DATA8(0x04);
	LCD_WR_DATA8(0x0D);
	LCD_WR_DATA8(0x11);
	LCD_WR_DATA8(0x13);
	LCD_WR_DATA8(0x2B);
	LCD_WR_DATA8(0x3F);
	LCD_WR_DATA8(0x54);
	LCD_WR_DATA8(0x4C);
	LCD_WR_DATA8(0x18);
	LCD_WR_DATA8(0x0D);
	LCD_WR_DATA8(0x0B);
	LCD_WR_DATA8(0x1F);
	LCD_WR_DATA8(0x23);

	LCD_WR_REG(0xE1);
	LCD_WR_DATA8(0xD0);
	LCD_WR_DATA8(0x04);
	LCD_WR_DATA8(0x0C);
	LCD_WR_DATA8(0x11);
	LCD_WR_DATA8(0x13);
	LCD_WR_DATA8(0x2C);
	LCD_WR_DATA8(0x3F);
	LCD_WR_DATA8(0x44);
	LCD_WR_DATA8(0x51);
	LCD_WR_DATA8(0x2F);
	LCD_WR_DATA8(0x1F);
	LCD_WR_DATA8(0x1F);
	LCD_WR_DATA8(0x20);
	LCD_WR_DATA8(0x23);
	LCD_WR_REG(0x21); 

	LCD_WR_REG(0x29); 
	
	LCD_Fill(0,0,LCD_W,LCD_H,BLACK);
}

//void LCD_Writ_Buffer(uint8_t *buf,uint16_t size)
//{
//    //HAL_SPI_Transmit_DMA(&hspi1,buf, size);
//    //HAL_SPI_Transmit(&hspi1,buf, size, 0xFFFF);
//}

void LCD_Writ_Bus(uint8_t dat) 
{	
    HAL_SPI_Transmit(&hspi1, &dat, 1, 0xFFFF);
}

void LCD_WR_DATA8(uint8_t dat)
{
	LCD_Writ_Bus(dat);
}


void LCD_WR_DATA(uint16_t dat)
{
	LCD_Writ_Bus(dat>>8);
	LCD_Writ_Bus(dat);
}

void LCD_WR_REG(uint8_t dat)
{
	LCD_DC_Clr();
	LCD_Writ_Bus(dat);
    LCD_DC_Set();
}

void LCD_Address_Set(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2)
{
	if(USE_HORIZONTAL==0)
	{
		LCD_WR_REG(0x2a);
		LCD_WR_DATA(x1);
		LCD_WR_DATA(x2);
		LCD_WR_REG(0x2b);
		LCD_WR_DATA(y1);
		LCD_WR_DATA(y2);
		LCD_WR_REG(0x2c);
	}
	else if(USE_HORIZONTAL==1)
	{
		LCD_WR_REG(0x2a);
		LCD_WR_DATA(x1);
		LCD_WR_DATA(x2);
		LCD_WR_REG(0x2b);
		LCD_WR_DATA(y1+80);
		LCD_WR_DATA(y2+80);
		LCD_WR_REG(0x2c);
	}
	else if(USE_HORIZONTAL==2)
	{
		LCD_WR_REG(0x2a);
		LCD_WR_DATA(x1);
		LCD_WR_DATA(x2);
		LCD_WR_REG(0x2b);
		LCD_WR_DATA(y1);
		LCD_WR_DATA(y2);
		LCD_WR_REG(0x2c);
	}
	else
	{
		LCD_WR_REG(0x2a);
		LCD_WR_DATA(x1+80);
		LCD_WR_DATA(x2+80);
		LCD_WR_REG(0x2b);
		LCD_WR_DATA(y1);
		LCD_WR_DATA(y2);
		LCD_WR_REG(0x2c);
	}
}
